home *** CD-ROM | disk | FTP | other *** search
/ PD Collection CD 1 / PD Collection CD 1.iso / programer2 / icon / Docs / Tr90-8 < prev    next >
Text File  |  1990-07-19  |  21KB  |  925 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10.  
  11.  
  12.  
  13.  
  14.                        Icon-C Interfaces*
  15.  
  16.  
  17.                         Ralph E. Griswold
  18.  
  19.  
  20.  
  21.  
  22.  
  23.                             TR 90-8b
  24.  
  25.  
  26.  
  27.  
  28.  
  29.  
  30.  
  31.  
  32.  
  33.  
  34.  
  35.  
  36.  
  37.  
  38.  
  39.  
  40.  
  41.  
  42.  
  43.  
  44.  
  45.  
  46.  
  47.  
  48.  
  49.           January 1, 1990; last revised March 11, 1990
  50.  
  51.  
  52.                  Department of Computer Science
  53.  
  54.                     The University of Arizona
  55.  
  56.                       Tucson, Arizona 85721
  57.  
  58.  
  59.  
  60.  
  61. *This work was supported by the National Science Foundation under
  62. Grant CCR-8713690.
  63.  
  64.  
  65.  
  66.  
  67.  
  68.  
  69.  
  70.  
  71.  
  72.  
  73.  
  74.  
  75.  
  76.                         Icon-C Interfaces
  77.  
  78.  
  79.  
  80.  
  81. 1.__Introduction
  82.  
  83.    Version 8 of Icon [1] supports two complementary features for
  84. calling C functions from Icon and vice versa. The two facilities
  85. are independent, but they may be used in conjunction and recur-
  86. sively.
  87.  
  88.    In their simplest form, these facilities can be used with only
  89. a little knowledge of how Icon is implemented. Sophisticated
  90. uses, however, require a good working knowledge of Icon data
  91. structures and Icon's internal operation [2,3].
  92.  
  93.  
  94. 2.__External_Functions
  95.  
  96.    The Icon function callout(x0, x1, ..., xn) allows C functions
  97. to be called from Icon programs. The first argument, x0, desig-
  98. nates the C function to be called. The remaining arguments of
  99. callout() are supplied to the C function (possibly in modified
  100. form). The method of specifying C functions varies with system
  101. and application.  In order to provide the necessary flexibility,
  102. callout() in turn calls a C function extcall(), which has the
  103. prototype
  104.  
  105.         dptr extcall(dptr argv, int argc, int *ip)
  106.  
  107. where argv is a pointer to an array of descriptors containing the
  108. arguments, argc is the number of arguments, and ip is a pointer
  109. to an integer status code.  The value returned by extcall() is a
  110. pointer to a descriptor if the computation is successful or NULL
  111. if it fails (which causes callout() to fail).
  112.  
  113.    A stub for extcall() is provided. It should be replaced by an
  114. appropriate C function. Alternatively, the Icon function cal-
  115. lout() can be modified to avoid the intermediate function call.
  116.  
  117. Designating_C_Functions
  118.  
  119.    A simple mechanism for designating C functions is to associate
  120. an integer with each one that can be called and use a C switch
  121. statement in extcall() to select the desired one.  This method is
  122. used in the first example in Appendix A. A better method is to
  123. use string names, as illustrated by the second function in Appen-
  124. dix A. On most systems, all the C functions to be called must be
  125. linked with Icon (presumably through references in extcall()). On
  126. a system like OS/2 that supports run-time dynamic linking, C
  127.  
  128.  
  129.  
  130.                               - 1 -
  131.  
  132.  
  133.  
  134.  
  135.  
  136.  
  137.  
  138.  
  139. functions can be loaded as needed during program execution.
  140.  
  141. Data_Interface
  142.  
  143.    The data interface also has to be handled by extcall() (or its
  144. equivalent). Arguments provided by Icon are in its descriptor
  145. format.  Icon contains conversion facilities in its repertoire of
  146. macros and utility functions.  Some that may be useful in exter-
  147. nal functions are:
  148.  
  149.      cvint(dp)      Converts the value in the descriptor pointed
  150.                     to by dp to an integer, returning CvtFail if
  151.                     the conversion cannot be performed.
  152.  
  153.      IntVal(d)      Accesses the (long) integer value of the
  154.                     integer descriptor d.
  155.  
  156.      MakeInt(i,dp). Constructs a integer descriptor pointed to by
  157.                     dp from the (long) integer i.
  158.  
  159.      cvstr(dp,sbuf) Converts the value in the descriptor pointed
  160.                     to by dp to a string in sbuf, returning
  161.                     CvtFail if the conversion cannot be per-
  162.                     formed.
  163.  
  164.      Qual(d)        Tests if d is a descriptor for a string.
  165.  
  166.      StrLen(d)      Accesses the length of the string in the
  167.                     descriptor d.
  168.  
  169.      StrLoc(d)      Accesses the address of the string in the
  170.                     descriptor d.
  171.  
  172.      qtos(dp,sbuf)  Constructs a C-style string from the descrip-
  173.                     tor pointed to by dp, placing it in sbuf, a
  174.                     buffer of length MaxCvtLen, if it is small
  175.                     enough or in the allocated string region if
  176.                     it is not.
  177.  
  178.      strreq(i)      Requests i characters of space in the allo-
  179.                     cated string region, returning Error if the
  180.                     space is not available.
  181.  
  182.      alcstr(sbuf,i) Copies the string of length i in sbuf to the
  183.                     allocated string region.
  184.  
  185.      blkreq(i)      Requests i bytes of space in the allocated
  186.                     block region, returning Error if the space is
  187.                     not available.
  188.  
  189.      cvreal(dp)     Converts the value in the descriptor pointed
  190.                     to by dp to a real number (floating-point
  191.                     double), returning CvtFail if the conversion
  192.                     fails.
  193.  
  194.  
  195.  
  196.                               - 2 -
  197.  
  198.  
  199.  
  200.  
  201.  
  202.  
  203.  
  204.  
  205.      makereal(r,dp) Constructs a real-number block for r and
  206.                     places a pointer to it in the descriptor
  207.                     pointed to by dp).
  208.  
  209.      GetReal(dp,r)  Places the floating-point double from the
  210.                     descriptor pointed to by dp into r.
  211.  
  212.    Conversion between Icon's structure values and C structs is
  213. more complicated and must be handled on a case-by-case basis.
  214.  
  215.    There are several global descriptors that may be useful in
  216. external functions:
  217.  
  218.         nulldesc    descriptor for the null value
  219.         zerodesc    descriptor for the Icon integer 0
  220.         onedesc     descriptor for the Icon integer 1
  221.         emptystr    descriptor for the empty string
  222.  
  223. See iconx/idata.c for others.
  224.  
  225. Error_Handling
  226.  
  227.    The status code pointed to by ip is used for error handling.
  228. It is -1 when extcall() is called, indicating the absence of an
  229. error. If an error occurs in extcall(), the status code should be
  230. set to the number of an Icon run-time error [1].  Error 216
  231. should be used if the designated C function is not found.
  232.  
  233.    In some cases the error number is set by a utility routine
  234. (strreq() is an example). In such cases, the status code should
  235. be set to zero. If there is a descriptor associated with the
  236. error, a pointer to that descriptor should be returned by ext-
  237. call(). If there is no specific descriptor associated with the
  238. error, extcall() should return NULL. See the examples in Appendix
  239. A.
  240.  
  241.    If the status code is not -1 when extcall() returns, callout()
  242. terminates program execution with a run-time error message
  243. corresponding to the value of the status code.
  244.  
  245.  
  246. 3.__Calling_Icon_from_a_C_Program
  247.  
  248.    The C function icon_call(), which is contained in Icon, is the
  249. complement of the Icon function callout(). The prototype for
  250. icon_call() is
  251.  
  252.         dptr icon_call(char *id, int nargs, dptr argv)
  253.  
  254. where id is the string name of a procedure in the Icon program to
  255. be run and nargs is the number of descriptors in the array argv.
  256. The procedure is called with the specified arguments.  The value
  257. returned is a pointer to the descriptor produced by the procedure
  258. if it returns or suspends, or NULL if the procedure fails.  The
  259.  
  260.  
  261.  
  262.                               - 3 -
  263.  
  264.  
  265.  
  266.  
  267.  
  268.  
  269.  
  270.  
  271. global variable call_error is set to a nonzero value if the pro-
  272. cedure is not found.  See Appendix B for examples.
  273.  
  274.    Before icon_call() is called the first time, Icon must be ini-
  275. tialized by calling icont_init(prog), where prog is the name of
  276. the icode file to be run. This loads the named icode file, sets
  277. up Icon's storage regions, and readies Icon for execution. Subse-
  278. quently, icon_call() can be called repeatedly.
  279.  
  280.  
  281. 4.__Compiling_Icon_for_C_Calling
  282.  
  283.    External functions (callout()) normally are enabled when Icon
  284. is compiled. They can be disabled by adding
  285.  
  286.         #define NoExternalFunctions
  287.  
  288. to define.h and recompiling.
  289.  
  290.    The ability to call an Icon program from C normally is dis-
  291. abled when Icon is compiled. It can be enabled by adding
  292.  
  293.         #define IconCalling
  294.  
  295. to define.h and recompiling.  Since the ability to call an Icon
  296. program from C increases the overhead of calling C functions from
  297. Icon (to support possible recursion), the ability to call an Icon
  298. program from C should not be enabled unless it is needed.
  299.  
  300.    To add external functions to Icon, it is only necessary to
  301. write the appropriate code, place it in a file named extcall.c to
  302. replace the distributed stub, and to link Icon with its object
  303. module in place of the one for the stub.
  304.  
  305.    To call Icon from a C program, it is necessary to provide the
  306. C program and use its object module in place of the one for
  307. istart.c, which is used by default (see the second example in
  308. Appendix B).  It is necessary to link the entire Icon run-time
  309. system with the calling program. The resulting executable file is
  310. quite large.
  311.  
  312.  
  313. 5.__Bugs
  314.  
  315.    There presently is no mechanism for resuming a procedure that
  316. suspends as the result of icon_call().
  317.  
  318.    A procedure called by icon_call() suspends by calling the Icon
  319. interpreter. There is no mechanism for unwinding the system stack
  320. in such a situation.
  321.  
  322.  
  323.  
  324.  
  325.  
  326.  
  327.  
  328.                               - 4 -
  329.  
  330.  
  331.  
  332.  
  333.  
  334.  
  335.  
  336.  
  337. 6.__Acknowledgements
  338.  
  339.    The facilities described here were based on ones written by
  340. Bill Griswold, using earlier work of Andy Heron. The implementa-
  341. tion for Version 8 of Icon was done by Sandra Miller and the
  342. author. Some of the material in this report was adapted from
  343. implementation notes provided by Bill Griswold.
  344.  
  345. References
  346.  
  347.  
  348. 1.   R. E. Griswold, Version 8 of Icon, The Univ. of Arizona
  349.      Tech. Rep. 90-1, 1990.
  350.  
  351. 2.   R. E. Griswold and M. T. Griswold, The Implementation of the
  352.      Icon Programming Language, Princeton University Press, 1986.
  353.  
  354. 3.   R. E. Griswold, Supplementary Information for the
  355.      Implementation of Version 8 of Icon, The Univ. of Arizona
  356.      Icon Project Document IPD112, 1990.
  357.  
  358.  
  359.  
  360.  
  361.  
  362.  
  363.  
  364.  
  365.  
  366.  
  367.  
  368.  
  369.  
  370.  
  371.  
  372.  
  373.  
  374.  
  375.  
  376.  
  377.  
  378.  
  379.  
  380.  
  381.  
  382.  
  383.  
  384.  
  385.  
  386.  
  387.  
  388.  
  389.  
  390.  
  391.  
  392.  
  393.  
  394.                               - 5 -
  395.  
  396.  
  397.  
  398.  
  399.  
  400.  
  401.  
  402.  
  403.              Appendix A - Examples of External Functions
  404.  
  405.  
  406. Example_1:_Functions_Designated_by_Numbers
  407.  
  408.         /*
  409.          * Example of calling C functions by integer codes.  Here it's
  410.          *  one of three UNIX functions:
  411.          *
  412.          *    1: getpid (get process identification)
  413.          *    2: getppid (get parent process identification)
  414.          *    3: getpgrp (get process group)
  415.          */
  416.  
  417.  
  418.         #include "../h/config.h"
  419.         #include "../h/rt.h"
  420.         #include "rproto.h"
  421.  
  422.  
  423.         struct descrip retval;             /* for returned value */
  424.  
  425.  
  426.         dptr extcall(dargv, argc, ip)
  427.         dptr dargv;
  428.         int argc;
  429.         int *ip;
  430.            {
  431.            int retcode;
  432.            int getpid(), getppid(), getpgrp();
  433.  
  434.  
  435.            *ip = -1;                       /* anticipate error-free execution */
  436.  
  437.  
  438.            if (cvint(dargv) == CvtFail) {  /* 1st argument must be a string */
  439.               *ip = 101;                   /* "integer expected" error number */
  440.               return dargv;                /* return offending value */
  441.               }
  442.  
  443.  
  444.  
  445.  
  446.  
  447.  
  448.  
  449.  
  450.  
  451.  
  452.  
  453.  
  454.  
  455.  
  456.  
  457.  
  458.  
  459.  
  460.                               - 6 -
  461.  
  462.  
  463.  
  464.  
  465.  
  466.  
  467.  
  468.  
  469.            switch ((int)IntVal(*dargv)) {
  470.               case 1:                      /* getpid */
  471.                  retcode = getpid();
  472.                  break;
  473.               case 2:                      /* getppid */
  474.                  retcode = getppid();
  475.                  break;
  476.               case 3:                      /* getpgrp */
  477.                  if (argc < 2) {
  478.                     *ip = 205;             /* no error number fits, really */
  479.                     return NULL;           /* no offending value */
  480.                     }
  481.                  dargv++;                  /* get to next value */
  482.                  if (cvint(dargv) == CvtFail) { /* 2nd argument must be integer */
  483.                     *ip = 101;             /* "integer expected" error number */
  484.                     return dargv;
  485.                     }
  486.                  retcode = getpgrp(IntVal(*dargv));
  487.                  break;
  488.  
  489.  
  490.               default:
  491.                  *ip = 216;                /* external function not found */
  492.                  return NULL;
  493.               }
  494.  
  495.  
  496.            MakeInt(retcode,&retval);       /* make an Icon integer for result */
  497.            return &retval;
  498.            }
  499.  
  500.  
  501. Functions_Designated_by_Name
  502.  
  503.         /*
  504.          * Example of calling C functions by their names.  Here it's just
  505.          *  chdir (change directory) or getwd (get path of current working directory).
  506.          */
  507.  
  508.  
  509.         #include "../h/config.h"
  510.         #include "../h/rt.h"
  511.         #include "rproto.h"
  512.  
  513.  
  514.         struct descrip retval;             /* for returned value */
  515.  
  516.  
  517.  
  518.  
  519.  
  520.  
  521.  
  522.  
  523.  
  524.  
  525.  
  526.                               - 7 -
  527.  
  528.  
  529.  
  530.  
  531.  
  532.  
  533.  
  534.  
  535.         dptr extcall(dargv, argc, ip)
  536.         dptr dargv;
  537.         int argc;
  538.         int *ip;
  539.            {
  540.            int len, retcode;
  541.            char sbuf1[MaxCvtLen];          /* for conversion on non-strings */
  542.            char sbuf2[MaxCvtLen];          /* for C-style string */
  543.            int chdir(), getwd();
  544.  
  545.  
  546.            *ip = -1;                       /* anticipate error-free execution */
  547.  
  548.  
  549.            if (cvstr(dargv, sbuf1) == CvtFail) {  /* 1st argument must be a string */
  550.               *ip = 103;                   /* "string expected" error number */
  551.               return dargv;                /* return offending value */
  552.               }
  553.  
  554.  
  555.            if (strncmp("chdir", StrLoc(*dargv), StrLen(*dargv)) == 0) {
  556.               if (argc < 2) {              /* must be a 2nd argument */
  557.                  *ip = 103;                /* no error number fits, really */
  558.                  return NULL;              /* no offedning value */
  559.                  }
  560.               dargv++;                     /* get to next argument */
  561.               if (cvstr(dargv, sbuf1) == CvtFail) {  /* 2nd argument must be a string */
  562.                  *ip = 103;                /* "string expected" error number */
  563.                  return dargv;             /* return offending value */
  564.                  }
  565.               qtos(dargv,sbuf2);           /* get C-style string in sbuf2 */
  566.               retcode = chdir(sbuf2);      /* try to change directory */
  567.               if (retcode == -1)           /* see if chdir failed */
  568.                  return (dptr)NULL;        /* signal failure */
  569.               return &zerodesc;            /* not a very useful result */
  570.               }
  571.  
  572.  
  573.            else if (strncmp("getwd", StrLoc(*dargv), StrLen(*dargv)) == 0) {
  574.               dargv++;                     /* get to next argument */
  575.               retcode = getwd(sbuf2);      /* get current working directory */
  576.               if (retcode == 0)            /* see if getwd failed */
  577.                  return NULL;              /* signal failure */
  578.               len = strlen(sbuf2);         /* length of resulting string */
  579.               if (strreq(len) == Error) {  /* need to allocate a copy of result */
  580.                  *ip = 0;                  /* zero since code is set elsewhere */
  581.                  return (dptr)NULL;        /* no offending value */
  582.                  }
  583.               StrLoc(retval) = alcstr(sbuf2,len);  /* allocate and copy the string */
  584.               StrLen(retval) = len;
  585.               return &retval;              /* return a pointer to the qualifier */
  586.               }
  587.  
  588.  
  589.  
  590.  
  591.  
  592.                               - 8 -
  593.  
  594.  
  595.  
  596.  
  597.  
  598.  
  599.  
  600.  
  601.            else {
  602.               *ip = 216;                   /* name is not one of those supported here */
  603.               return dargv;                /* return pointer to offending value */
  604.               }
  605.            }
  606.  
  607.  
  608.  
  609.  
  610.  
  611.  
  612.  
  613.  
  614.  
  615.  
  616.  
  617.  
  618.  
  619.  
  620.  
  621.  
  622.  
  623.  
  624.  
  625.  
  626.  
  627.  
  628.  
  629.  
  630.  
  631.  
  632.  
  633.  
  634.  
  635.  
  636.  
  637.  
  638.  
  639.  
  640.  
  641.  
  642.  
  643.  
  644.  
  645.  
  646.  
  647.  
  648.  
  649.  
  650.  
  651.  
  652.  
  653.  
  654.  
  655.  
  656.  
  657.  
  658.                               - 9 -
  659.  
  660.  
  661.  
  662.  
  663.  
  664.  
  665.  
  666.  
  667.               Appendix B - Examples of Calling Icon
  668.  
  669.  
  670. Example_1:_Calling_Icon_Procedures_from_the_Command_Line
  671.  
  672.         /*
  673.          *  Demonstration program to call an Icon procedure with arguments.  This
  674.          *  program is used as
  675.          *
  676.          *        iconval iprog proc arg1 arg2 ...
  677.          *
  678.          *  where iprog is the name of the Icon icode file, proc is the name of
  679.          *  a procedure in it, and arg1, arg2, ... are arguments passed to proc.
  680.          *  It prints out the result if proc succeeds or notes if the procedure fails.
  681.          *  It prints a diagnostic message if proc is not a procedure in iprog.
  682.          */
  683.  
  684.  
  685.         #include "../h/config.h"
  686.         #include "../h/rt.h"
  687.         #include "rproto.h"
  688.  
  689.  
  690.  
  691.  
  692.         extern int call_error;
  693.  
  694.  
  695.         novalue main(argc,argv)
  696.  
  697.  
  698.         int argc;
  699.         char *argv[];
  700.            {
  701.            int clargc;
  702.            char **clargv;
  703.            dptr retval, iargv;
  704.            int i;
  705.            char sbuf[MaxCvtLen];
  706.  
  707.  
  708.            /*
  709.             * Read in the icode file argv[1] and initialize the Icon system.
  710.             *  This must be done for any C program calling Icon.
  711.             */
  712.            icon_init(argv[1]);
  713.  
  714.  
  715.  
  716.  
  717.  
  718.  
  719.  
  720.  
  721.  
  722.  
  723.  
  724.                              - 10 -
  725.  
  726.  
  727.  
  728.  
  729.  
  730.  
  731.  
  732.  
  733.            /*
  734.             * Skip the names of the executable and the file it processes.  It
  735.             *  is only necessary to get the the procedure name and its arguments from
  736.             *  the command line.
  737.             */
  738.            clargv = argv + 2;
  739.            clargc = argc - 3;
  740.  
  741.  
  742.            fprintf(stderr,"program=%s0,*clargv);
  743.            fflush(stderr);
  744.            /*
  745.             * Malloc space for the list of descriptors and create Icon qualifiers
  746.             *  for each argument.
  747.             */
  748.            iargv = (dptr)malloc(clargc * sizeof(struct descrip));
  749.            for (i = 0; i < clargc; i++) {
  750.               StrLoc(iargv[i]) = clargv[i + 1];
  751.               StrLen(iargv[i]) = strlen(clargv[i + 1]);
  752.              }
  753.            retval = icon_call(*clargv, clargc, iargv);
  754.            if (call_error) {
  755.               fprintf(stderr,"procedure not found0);
  756.               fflush(stderr);
  757.               c_exit(ErrorExit);
  758.               }
  759.            if (retval == NULL)
  760.               fprintf(stdout,"evaluation failed0);
  761.            else {
  762.               /* Check type of result returned.  Don't attempt to print anything
  763.                *  but strings and integers here.
  764.                */
  765.               if (Qual(*retval)) {
  766.                 qtos(retval,sbuf);
  767.                 fprintf(stdout,"
  768.                 }
  769.               else if (Type(*retval) == T_Integer)
  770.                 fprintf(stdout,"%ld0,IntVal(*retval));
  771.               else
  772.                 fprintf(stdout,"type=%d0,Type(*retval));
  773.               fflush(stdout);
  774.               }
  775.            c_exit(NormalExit);
  776.  
  777.  
  778.            }
  779.  
  780.  
  781. Example_2:_Main_Program_for_Calling_Icon
  782.  
  783.         /*
  784.          *  Main program if Icon is called as a subprogram.
  785.          */
  786.  
  787.  
  788.  
  789.  
  790.                              - 11 -
  791.  
  792.  
  793.  
  794.  
  795.  
  796.  
  797.  
  798.  
  799.         #include "../h/config.h"
  800.         #include "../h/rt.h"
  801.         #include "rproto.h"
  802.  
  803.  
  804.         #ifdef IconCalling
  805.  
  806.  
  807.         novalue main(argc,argv)
  808.  
  809.  
  810.         int argc;
  811.         char *argv[];
  812.            {
  813.            int clargc;
  814.            char **clargv;
  815.            int i;
  816.            struct descrip darg;
  817.  
  818.  
  819.            /*
  820.             * Set up standard Icon interface.  This is only necessary so that
  821.             *  Icon can behave normally as if it were the main program.
  822.             *  It is not necessary if Icon is called by a C program for another
  823.             *  purpose.
  824.             */
  825.  
  826.  
  827.         #if VMS
  828.            redirect(&argc, argv, 0);
  829.         #endif                             /* VMS */
  830.  
  831.  
  832.            icon_setup(argc, argv, &i);
  833.            while (i--) {                   /* skip option arguments */
  834.               argc--;
  835.               argv++;
  836.               }
  837.  
  838.  
  839.            if (!argc)
  840.               error("no icode file specified");
  841.  
  842.  
  843.            /*
  844.             * Read in the icode file argv[1] and initialize the Icon system.
  845.             *  This must be done for any C program calling Icon.
  846.             */
  847.            icon_init(argv[1]);
  848.  
  849.  
  850.  
  851.  
  852.  
  853.  
  854.  
  855.  
  856.                              - 12 -
  857.  
  858.  
  859.  
  860.  
  861.  
  862.  
  863.  
  864.  
  865.            /*
  866.             * Skip the names of the executable and the file it processes.  This
  867.             *  is necessary only to get the right arguments from the command line
  868.             *  to call Icon as if it were the main program and hence provide
  869.             *  the correct values in the list that is the argument of Icon's main
  870.             *  procedure. This is not necessary if Icon is called from C for
  871.             *  another purpose.
  872.             */
  873.            clargv = argv + 2;
  874.            clargc = argc - 2;
  875.  
  876.  
  877.            /*
  878.             * Set up a temporary stack and build the necessary list
  879.             *  to call main.
  880.             */
  881.            sp = stack + Wsizeof(struct b_coexpr);
  882.  
  883.  
  884.            PushNull;
  885.            argp = (dptr)(sp - 1);
  886.            for (i = 0; i < clargc; i++) {
  887.               PushAVal(strlen(clargv[i]));
  888.               PushVal(clargv[i]);
  889.               }
  890.            Ollist(clargc, argp);
  891.  
  892.  
  893.            /*
  894.             * Now that the list is computed, copy its descriptor off the
  895.             *  stack (which is about to be destroyed), reset the argument
  896.             *  pointer, and make the call to the Icon main procedure.
  897.             */
  898.  
  899.  
  900.            darg = *argp;
  901.            argp = 0;
  902.            icon_call("main", 1, &darg);    /* return signal and value ignored */
  903.            c_exit(NormalExit);
  904.  
  905.  
  906.            }
  907.         #else                              /* IconCalling */
  908.         static char x;                     /* avoid empty module */
  909.         #endif                             /* IconCalling */
  910.  
  911.  
  912.  
  913.  
  914.  
  915.  
  916.  
  917.  
  918.  
  919.  
  920.  
  921.  
  922.                              - 13 -
  923.  
  924.  
  925.